<?php


namespace App\Http\Controllers\User;


use App\Http\Common\BaseController;
use App\Http\Validator\WeeklyValidator;
use App\Models\Semester;
use App\Models\Label;
use App\Models\Weekly;
use App\Models\WeeklyLabel;
use App\Models\WeeklyLikes;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Redis;
use App\Models\Role;
use App\Models\User;
use App\Models\UserRole;
use App\Models\AdminFunctions;
use App\Models\Notice;

class WeekliesController extends BaseController
{
    /**
     * 获取所有周报
     * @param Request $request
     * @param $label
     * @param $type
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function getWeeklyList(Request $request, $label, $type){
        //label 为0则为推荐
        //type 0：热门 1：最新
        //page 分页

        if ($label == 0){
            $weeklyData = Weekly::join('users', 'weeklies.user_id', 'users.id')
                ->select(['weeklies.id', 'users.username', 'weeklies.create_time', 'weeklies.title', 'weeklies.content', 'weeklies.edit', 'weeklies.browse', 'weeklies.background', 'weeklies.text'])
                ->where('is_deleted', 0);
        }else{
            $weeklyData = WeeklyLabel::join('labels', 'weekly_labels.label_id', 'labels.id')
                ->join('weeklies', 'weekly_labels.weekly_id', 'weeklies.id')
                ->join('users', 'weeklies.user_id', 'users.id')
                ->select(['weeklies.id', 'users.username', 'weeklies.create_time', 'weeklies.title', 'weeklies.content', 'weeklies.edit', 'weeklies.browse', 'weeklies.background', 'labels.label', 'weeklies.text'])
                ->where([
                    'weekly_labels.label_id'    => $label,
                    'is_deleted'        =>  0
                ]);
        }

        if ($type == 0){
            $weeklyData = $weeklyData->orderBy('weeklies.browse', 'desc');
        }elseif ($type == 1){
            $weeklyData = $weeklyData->orderBy('weeklies.create_time', 'desc');
        }

        //判断page参数是否存在，不存在则为1
        if (!$page = $request->get('page')) $page = 1;

        $weeklyData = $weeklyData->offset(7 * ($page - 1))
            ->limit(7)
            ->get()
            ->toArray();

        if (!$weeklyData) return $this->returnJson(BaseController::DATA_NOTFOUND, '暂无周报数据');

        foreach ($weeklyData as $key => $value){
            //点赞
            $likes = WeeklyLikes::where([
                'weekly_id' =>  $value['id']
            ])->count();
            $weeklyData[$key]['likes'] = $likes;

            //标签
            $data = Weekly::join('weekly_labels', 'weeklies.id', 'weekly_id')
                ->join('labels', 'weekly_labels.label_id', 'labels.id')
                ->where('weeklies.id', $value['id'])
                ->select(['labels.id', 'labels.label'])
                ->get();
            $weeklyData[$key]['label'] = $data;

            //转换时间
            $weeklyData[$key]['create_time'] = $this->timeTransform($value['create_time']);
        }

        return $this->returnJson(BaseController::SUCCESS, '获取周报成功', $weeklyData);
    }

    /**
     * 用户查看周报（一篇）
     * @param $id
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function getWeekly($id){
         $weeklyData = Weekly::join('users', 'weeklies.user_id', 'users.id')
             ->where([
             'weeklies.id'       =>  $id
         ])->first(['weeklies.id', 'weeklies.title', 'weeklies.content', 'weeklies.edit', 'weeklies.create_time', 'weeklies.browse', 'users.username', 'users.introduce']);

        if (!$weeklyData) return $this->returnJson(BaseController::DATA_NOTFOUND, '您查询的周报不存在');

        //标签
        $data = Weekly::join('weekly_labels', 'weeklies.id', 'weekly_id')
            ->join('labels', 'weekly_labels.label_id', 'labels.id')
            ->where('weeklies.id', $weeklyData['id'])
            ->select(['labels.id', 'labels.label'])
            ->get();
        $weeklyData['label'] = $data;

        //点赞
        $likes = WeeklyLikes::where([
            'weekly_id' =>  $weeklyData['id']
        ])->count();
        $weeklyData['likes'] = $likes;

        //转换时间
        $weeklyData['create_time'] = date('Y年m月d日 H:i', $weeklyData['create_time']);

        return $this->returnJson(BaseController::SUCCESS, '获取一篇周报成功', $weeklyData);
    }

    /**
     * 用户周报点赞
     * @param Request $request
     * @param $id
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function weeklyLike(Request $request, $id){
        //判断周报是否存在
        $is_weekly = Weekly::where('id', $id)->first();
        if (!$is_weekly) return $this->returnJson(BaseController::DATA_NOTFOUND, '周报不存在');

        //判断当前用户是否点赞
        $likes = WeeklyLikes::where([
            'user_id' => $request->userId,
            'weekly_id' => $id
        ])->first();
        if ($likes) return $this->returnJson(BaseController::LIKED, '当前用户已点赞');

        //点赞
        WeeklyLikes::insert([
            'user_id' => $request->userId,
            'weekly_id' => $id
        ]);
        return $this->returnJson(BaseController::SUCCESS, '用户点赞成功');
    }

    /**
     * 更新周报浏览量
     * @param $id
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function updateWeeklyBrowse($id, Request $request){
        //判断周报是否存在
        $is_weekly = Weekly::where([
            'id'    => $id,
            'is_deleted' => '0'
        ])->first();
        if (!$is_weekly) return $this->returnJson(BaseController::DATA_NOTFOUND, '周报不存在');

        $browseKey = 'weekly' . $id . $request->userId;

        //判断当前用户已经浏览
        if(Redis::get($browseKey)){
            return $this->returnJson(BaseController::SUCCESS, '当前用户已浏览');
        }

        //修改周报浏览
        Weekly::where('id', $id)->increment('browse', 1);

        $weekly = [
            'userId'    => $request->userId,
            'weekly_id' => $id
        ];

        Redis::setex($browseKey, 60 * 60, json_encode($weekly));
        return $this->returnJson(BaseController::SUCCESS, '周报浏览量+1');
    }

    /**
     * 用户添加周报
     * @param Request $request
     * @param WeeklyValidator $weeklyValidator
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function addWeekly(Request $request, WeeklyValidator $weeklyValidator){
        $params = $request->only(['title', 'content', 'label', 'edit', 'background', 'text']);

        //判断参数格式
        if (!$weeklyValidator->setScene('addWeekly')->check($params)){
            return $this->returnJson(BaseController::FIELD_ERROR, $weeklyValidator->getError());
        }

        //判断周报标签是否大于2个
        if (count($params['label']) > 2) return $this->returnJson(BaseController::FIELD_ERROR, "周报标签只能有两个");

        DB::beginTransaction();
        try {
            //插入周报
            $weeklyId = Weekly::insertGetId([
                'semesters_id'  =>  $this->getNewSemester(),
                'weeks'     => $this->getNewWeeks(),
                'user_id'   => $request->userId,
                'date'      => time(),
                'title'     => $params['title'],
                'content'   => $params['content'],
                'create_time' => time(),
                'edit'      => $params['edit'],
                'background'=> $params['background'],
                'text'      => $params['text']
            ]);

            //插入标签
            foreach ($params['label'] as $value) {
                WeeklyLabel::insert([
                    'weekly_id' =>  $weeklyId,
                    'label_id'  =>  $value
                ]);
            }

            DB::commit();
        }catch (\Exception $e){
            DB::rollBack();
            return $this->returnJson(BaseController::ERROR, '周报添加失败');
        }

        return $this->returnJson(BaseController::SUCCESS, '周报添加成功');
    }

    /**
     * 周报上传文件
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function weeklyUploadFile(Request $request){
        $file = $request->file('file');
        $userId = $request->post('userId');

        if ($file->isValid()){
            //获取文件后缀
            $suffix = $file->getClientOriginalExtension();

            //判断文件后缀
            $rule = ['jpg', 'png', 'gif'];
            if (!in_array($suffix, $rule)) return $this->returnJson(BaseController::FIELD_ERROR, '上传的文件格式必需为jpg/png/gif');

            //判断文件大小
            $fileSize = $file->getSize();
            if ($fileSize > 10 * 1024 * 1024){
                return $this->returnJson(BaseController::FIELD_ERROR, '上传的文件必须在10m以内');
            }


            $fileUrl = md5(time() . $file->getClientOriginalName()) . '.' . $suffix;
            if (!$filename = $this->uploadOss('weeklyFile/' . $userId, $fileUrl, $file->getRealPath())){
                return response([
                    'errno' =>  1,
                    'message'   =>  '上传失败'
                ]);
            }
        }
        return response([
            'errno' =>  0,
            'data'  => [
                'url'   =>  $filename['oss-request-url'],
                'alt'   =>  '',
                'href'  =>  $filename['oss-request-url']
            ]
        ]);
    }

    /**
     * 周报删除文件
     * @param Request $request
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function weeklyDeleteFile(Request $request){
        $fileUrl = $request->input('url');

        //判断参数格式
        if (empty($fileUrl)){
            return $this->returnJson(BaseController::FIELD_ERROR, '传入的路径不能为空');
        }

        //获取需要截取的内容
        if (strstr($fileUrl, 'http://')){
            $prefix = "http://" . env('BUCKET') . '.' . env('ENDPOINT') . '/';
        }else{
            $prefix = "https://" . env('BUCKET') . '.' . env('ENDPOINT') . '/';
        }
        $exist = substr($fileUrl, strlen($prefix));

        //判断文件是否存在
        if (!$this->isFileExist($exist)){
            return $this->returnJson(BaseController::DATA_NOTFOUND, '删除的文件不存在');
        }

        //删除文件
        if (!$this->deleteOss($exist)){
            return $this->returnJson(BaseController::ERROR, '文件删除失败');
        }

        return $this->returnJson(BaseController::SUCCESS, '文件删除成功');
    }

    /**
     * 获取所有周报的标签
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function releaseLabel(){
        $labelAll = Label::select(['id as value', 'label'])->get();
        return $this->returnJson(BaseController::SUCCESS, '获取所有周报标签', $labelAll);
    }

    /**
     * 优秀作者排行榜
     * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\Routing\ResponseFactory|\Illuminate\Http\Response
     */
    public function excellentAuthor(){
        $data = User::join('weeklies', 'users.id', 'weeklies.user_id')
            ->join('grades', 'users.grade_id', 'grades.id')
            ->select('users.id', 'users.username', 'users.introduce', 'grades.grade',DB::raw('count("weeklies.id") as num'))
            ->groupBy('users.id')
            ->orderBy('num', 'desc')
            ->limit(8)
            ->get();
        return $this->returnJson(BaseController::SUCCESS, '优秀作者获取成功', $data);
    }
}
